/***********************************************************************************************************
============================================================================================================
 Bits Download Manager
 http://www.codeplex.com/BITSDownloadMgr

 Component:BITSDownloadMgr.Interop
 File Name:BITSInterop.cs
 
 
============================================================================================================
 Copyright (C) 2004-2007 Microsoft Corporation

 This source is subject to the Microsoft Public License (Ms-PL).
 See http:www.microsoft.com/resources/sharedsource/licensingbasics/sharedsourcelicenses.mspx.
 All other rights reserved.

 THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
 OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
 LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
 FITNESS FOR A PARTICULAR PURPOSE.
============================================================================================================
***********************************************************************************************************/


//============================================================================================================
// Microsoft Updater Application Block for .NET
//  http://msdn.microsoft.com/library/en-us/dnbda/html/updater.asp
//	
// BITSInterop.cs
//
// Interop definitions for BITS COM interop.
// 
// For more information see the Updater Application Block Implementation Overview. 
// 
//============================================================================================================
// Copyright (C) 2000-2001 Microsoft Corporation
// All rights reserved.
// THIS CODE AND INFORMATION IS PROVIDED "AS IS" WITHOUT WARRANTY
// OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING BUT NOT
// LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND/OR
// FITNESS FOR A PARTICULAR PURPOSE.
//============================================================================================================





using System;
using System.Runtime.InteropServices;
using System.Security.Permissions;
using BitsDownloadMgr.Interop;

namespace BitsDownloadMgr.Interop
{
	// InteropBits.cs
	// COM Interop C# classes for accessing BITS API.
	// Refer to MSDN for Details: 
	// http://msdn.microsoft.com/library/en-us/bits/bits/bits_reference.asp
	// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/service_accounts_and_bits.asp 
	// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/enumerating_jobs_in_the_transfer_queue.asp
	// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/bits/bits/handling_errors.asp?frame=true
	// http://msdn.microsoft.com/library/default.asp?url=/library/en-us/dnwxp/html/WinXP_BITS.asp 
	// http://msdn.microsoft.com/msdnmag/issues/03/02/BITS/default.aspx 

	/// <summary>
	/// BackgroundCopyManager Class
	/// </summary>
	[GuidAttribute("4991D34B-80A1-4291-83B6-3328366B9097")]
	[ClassInterfaceAttribute(ClassInterfaceType.None)]
	[ComImportAttribute()]
	[SecurityPermission(SecurityAction.Demand, UnmanagedCode = true)]
	internal class BackgroundCopyManager
	{
	}

	/// <summary>
	/// Use the IBackgroundCopyManager interface to create transfer jobs, 
	/// retrieve an enumerator object that contains the jobs in the queue, 
	/// and to retrieve individual jobs from the queue.
	/// </summary>
	[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	[GuidAttribute("5CE34C0D-0DC9-4C1F-897C-DAA1B78CEE7C")]
	[ComImportAttribute()]
	internal  interface IBackgroundCopyManager 
	{
		
		/// <summary>
		/// Creates a new transfer job
		/// </summary>
		void CreateJob([MarshalAs(UnmanagedType.LPWStr)] string DisplayName, BitsJobType Type, out Guid pJobId, [MarshalAs(UnmanagedType.Interface)] out IBackgroundCopyJob ppJob);
		
		/// <summary>
		/// Retrieves a given job from the queue
		/// </summary>
		void GetJob(ref Guid jobID, [MarshalAs(UnmanagedType.Interface)] out IBackgroundCopyJob ppJob);
		
		/// <summary>
		/// Retrieves an enumerator object that you use to enumerate jobs in the queue
		/// </summary>
		void EnumJobs(uint dwFlags, [MarshalAs(UnmanagedType.Interface)] out IEnumBackgroundCopyJobs ppenum);
		
		/// <summary>
		/// Retrieves a description for the given error code
		/// </summary>
		void GetErrorDescription([MarshalAs(UnmanagedType.Error)] int hResult, uint LanguageId, [MarshalAs(UnmanagedType.LPWStr)] out string pErrorDescription);
	}

 
	/// <summary>
	/// Use the IBackgroundCopyJob interface to add files to the job, 
	/// set the priority level of the job, determine the state of the
	/// job, and to start and stop the job.
	/// </summary>
	[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	[GuidAttribute("37668D37-507E-4160-9316-26306D150B12")]
	[ComImportAttribute()]
	internal  interface IBackgroundCopyJob 
	{
		
		/// <summary>
		/// Adds multiple files to the job
		/// </summary>
		void AddFileSet(uint cFileCount, [MarshalAs(UnmanagedType.LPArray)] _BG_FILE_INFO[] pFileSet);

		/// <summary>
		/// Adds a single file to the job
		/// </summary>
		void AddFile([MarshalAs(UnmanagedType.LPWStr)] string RemoteUrl, [MarshalAs(UnmanagedType.LPWStr)] string LocalName);

		
		/// <summary>
		/// Returns an interface pointer to an enumerator
		/// object that you use to enumerate the files in the job
		/// </summary>
		void EnumFiles([MarshalAs(UnmanagedType.Interface)] out IEnumBackgroundCopyFiles pEnum);

		
		/// <summary>
		/// Pauses the job
		/// </summary>
		void Suspend();

		
		/// <summary>
		/// Restarts a suspended job
		/// </summary>
		void Resume();

		
		/// <summary>
		/// Cancels the job and removes temporary files from the client
		/// </summary>
		void Cancel();
		
		/// <summary>
		/// Ends the job and saves the transferred files on the client
		/// </summary>
		void Complete();
		
		/// <summary>
		/// Retrieves the identifier of the job in the queue
		/// </summary>
		void GetId(out Guid pVal);
		
		/// <summary>
		/// Retrieves the type of transfer being performed, 
		/// such as a file download
		/// </summary>
		void GetType(out BitsJobType pVal);
		
		/// <summary>
		/// Retrieves job-related progress information, 
		/// such as the number of bytes and files transferred 
		/// to the client
		/// </summary>
		void GetProgress(out _BG_JOB_PROGRESS pVal);
		
		/// <summary>
		/// Retrieves timestamps for activities related
		/// to the job, such as the time the job was created
		/// </summary>
		void GetTimes(out _BG_JOB_TIMES pVal);
		
		/// <summary>
		/// Retrieves the state of the job
		/// </summary>
		void GetState(out BitsJobState pVal);
		
		/// <summary>
		/// Retrieves an interface pointer to 
		/// the error object after an error occurs
		/// </summary>
		void GetError([MarshalAs(UnmanagedType.Interface)] out IBackgroundCopyError ppError);
		
		/// <summary>
		/// Retrieves the job owner's identity
		/// </summary>
		void GetOwner([MarshalAs(UnmanagedType.LPWStr)] out string pVal);
		
		/// <summary>
		/// Specifies a display name that identifies the job in 
		/// a user interface
		/// </summary>
		void SetDisplayName([MarshalAs(UnmanagedType.LPWStr)] string Val);
		
		/// <summary>
		/// Retrieves the display name that identifies the job
		/// </summary>
		void GetDisplayName([MarshalAs(UnmanagedType.LPWStr)] out string pVal);
		
		/// <summary>
		/// Specifies a description of the job
		/// </summary>
		void SetDescription([MarshalAs(UnmanagedType.LPWStr)] string Val);
		
		/// <summary>
		/// Retrieves the description of the job
		/// </summary>
		void GetDescription([MarshalAs(UnmanagedType.LPWStr)] out string pVal);
		
		/// <summary>
		/// Specifies the priority of the job relative to 
		/// other jobs in the transfer queue
		/// </summary>
		void SetPriority(BitsJobPriority Val);

		/// <summary>
		/// Retrieves the priority level you have set for the job.
		/// </summary>
		void GetPriority(out BitsJobPriority pVal);
		
		/// <summary>
		/// Specifies the type of event notification to receive
		/// </summary>
		void SetNotifyFlags(BG_NOTIFY_FLAGS Val);
		
		/// <summary>
		/// Retrieves the event notification (callback) flags 
		/// you have set for your application.
		/// </summary>
		void GetNotifyFlags(out BG_NOTIFY_FLAGS pVal);
		
		/// <summary>
		/// Specifies a pointer to your implementation of the 
		/// IBackgroundCopyCallback interface (callbacks). The 
		/// interface receives notification based on the event 
		/// notification flags you set
		/// </summary>
		void SetNotifyInterface([MarshalAs(UnmanagedType.Interface)] IBackgroundCopyCallback Val);
		
		/// <summary>
		/// Retrieves a pointer to your implementation 
		/// of the IBackgroundCopyCallback interface (callbacks).
		/// </summary>
		void GetNotifyInterface([MarshalAs(UnmanagedType.Interface)] out IBackgroundCopyCallback pVal);
		
		/// <summary>
		/// Specifies the minimum length of time that BITS waits after 
		/// encountering a transient error condition before trying to 
		/// transfer the file
		/// </summary>
		void SetMinimumRetryDelay(uint Seconds);
		
		/// <summary>
		/// Retrieves the minimum length of time that BITS waits after 
		/// encountering a transient error condition before trying to 
		/// transfer the file
		/// </summary>
		void GetMinimumRetryDelay(out uint Seconds);
		
		/// <summary>
		/// Specifies the length of time that BITS continues to try to 
		/// transfer the file after encountering a transient error 
		/// condition
		/// </summary>
		void SetNoProgressTimeout(uint Seconds);
		
		/// <summary>
		/// Retrieves the length of time that BITS continues to try to 
		/// transfer the file after encountering a transient error condition
		/// </summary>
		void GetNoProgressTimeout(out uint Seconds);
		
		/// <summary>
		/// Retrieves the number of times the job was interrupted by 
		/// network failure or server unavailability
		/// </summary>
		void GetErrorCount(out uint Errors);
		
		/// <summary>
		/// Specifies which proxy to use to transfer the files
		/// </summary>
		void SetProxySettings(BitsJobProxyUsage ProxyUsage, [MarshalAs(UnmanagedType.LPWStr)] string ProxyList, [MarshalAs(UnmanagedType.LPWStr)] string ProxyBypassList);
		
		/// <summary>
		/// Retrieves the proxy settings the job uses to transfer the files
		/// </summary>
		void GetProxySettings(out BitsJobProxyUsage pProxyUsage, [MarshalAs(UnmanagedType.LPWStr)] out string pProxyList, [MarshalAs(UnmanagedType.LPWStr)] out string pProxyBypassList);
		
		/// <summary>
		/// Changes the ownership of the job to the current user
		/// </summary>
		void TakeOwnership();
	}

	/// <summary>
	/// Use the information in the IBackgroundCopyError interface to 
	/// determine the cause of the error and if the transfer process 
	/// can proceed
	/// </summary>
	[GuidAttribute("19C613A0-FCB8-4F28-81AE-897C3D078F81")]
	[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	[ComImportAttribute()]
	internal  interface IBackgroundCopyError 
	{
		/// <summary>
		/// Retrieves the error code and identify the context 
		/// in which the error occurred
		/// </summary>
		void GetError(out BitsErrorContext pContext, [MarshalAs(UnmanagedType.Error)] out int pCode);

		/// <summary>
		/// Retrieves an interface pointer to the file object 
		/// associated with the error
		/// </summary>
		void GetFile([MarshalAs(UnmanagedType.Interface)] out IBackgroundCopyFile pVal);

		/// <summary>
		/// Retrieves the error text associated with the error
		/// </summary>
		void GetErrorDescription(uint LanguageId, [MarshalAs(UnmanagedType.LPWStr)] out string pErrorDescription);

		/// <summary>
		/// Retrieves a description of the context in which the error occurred
		/// </summary>
		void GetErrorContextDescription(uint LanguageId, [MarshalAs(UnmanagedType.LPWStr)] out string pContextDescription);

		/// <summary>
		/// Retrieves the protocol used to transfer the file
		/// </summary>
		void GetProtocol([MarshalAs(UnmanagedType.LPWStr)] out string pProtocol);
	}

	/// <summary>
	/// Use the IEnumBackgroundCopyJobs interface to enumerate the list 
	/// of jobs in the transfer queue. To get an IEnumBackgroundCopyJobs 
	/// interface pointer, call the IBackgroundCopyManager::EnumJobs method
	/// </summary>
	[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	[GuidAttribute("1AF4F612-3B71-466F-8F58-7B6F73AC57AD")]
	[ComImportAttribute()]
	internal  interface IEnumBackgroundCopyJobs
	{
		/// <summary>
		/// Retrieves a specified number of items in the enumeration sequence
		/// </summary>
		void Next(uint celt, [MarshalAs(UnmanagedType.Interface)] out IBackgroundCopyJob rgelt, out uint pceltFetched);

		/// <summary>
		/// Skips a specified number of items in the enumeration sequence
		/// </summary>
		void Skip(uint celt);

		/// <summary>
		/// Resets the enumeration sequence to the beginning.
		/// </summary>
		void Reset();

		/// <summary>
		/// Creates another enumerator that contains the same 
		/// enumeration state as the current one
		/// </summary>
		void Clone([MarshalAs(UnmanagedType.Interface)] out IEnumBackgroundCopyJobs ppenum);

		/// <summary>
		/// Returns the number of items in the enumeration
		/// </summary>
		void GetCount(out uint puCount);
	}

	/// <summary>
	/// Use the IEnumBackgroundCopyFiles interface to enumerate the files 
	/// that a job contains. To get an IEnumBackgroundCopyFiles interface 
	/// pointer, call the IBackgroundCopyJob::EnumFiles method
	/// </summary>
	[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	[GuidAttribute("CA51E165-C365-424C-8D41-24AAA4FF3C40")]
	[ComImportAttribute()]
	internal  interface IEnumBackgroundCopyFiles 
	{
		/// <summary>
		/// Retrieves a specified number of items in the enumeration sequence
		/// </summary>
		void Next(uint celt, [MarshalAs(UnmanagedType.Interface)] out IBackgroundCopyFile rgelt, out uint pceltFetched);
		
		/// <summary>
		/// Skips a specified number of items in the enumeration sequence
		/// </summary>
		void Skip(uint celt);

		/// <summary>
		/// Resets the enumeration sequence to the beginning
		/// </summary>
		void Reset();

		/// <summary>
		/// Creates another enumerator that contains the same 
		/// enumeration state as the current enumerator
		/// </summary>
		void Clone([MarshalAs(UnmanagedType.Interface)] out IEnumBackgroundCopyFiles ppenum);

		/// <summary>
		/// Retrieves the number of items in the enumeration
		/// </summary>
		void GetCount(out uint puCount);
	}

	/// <summary>
	///  The IBackgroundCopyFile interface contains information about a file 
	///  that is part of a job. For example, you can use the interfaces methods
	///  to retrieve the local and remote names of the file and transfer progress
	///  information
	/// </summary>
	[GuidAttribute("01B7BD23-FB88-4A77-8490-5891D3E4653A")]
	[InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
	[ComImportAttribute()]
	internal  interface IBackgroundCopyFile 
	{
		/// <summary>
		/// Retrieves the remote name of the file
		/// </summary>
		void GetRemoteName([MarshalAs(UnmanagedType.LPWStr)] out string pVal);

		/// <summary>
		/// Retrieves the local name of the file
		/// </summary>
		void GetLocalName([MarshalAs(UnmanagedType.LPWStr)] out string pVal);
		
		/// <summary>
		/// Retrieves the progress of the file transfer
		/// </summary>
		void GetProgress(out _BG_FILE_PROGRESS pVal);
	}

    /// <summary>
    /// Implement the IBackgroundCopyCallback interface to receive notification 
    /// that a job is complete, has been modified, or is in error. Clients use 
    /// this interface instead of polling for the status of the job. 
    /// To receive notifications, call the IBackgroundCopyJob::SetNotifyInterface 
    /// method to specify the interface pointer to your IBackgroundCopyCallback 
    /// implementation. To specify which notifications you want to receive, call 
    /// the IBackgroundCopyJob::SetNotifyFlags method.
    /// </summary>
    [InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]
    [GuidAttribute("97EA99C7-0186-4AD4-8DF9-C5B4E0ED6B22")]
    [ComImportAttribute()]
    internal interface IBackgroundCopyCallback
    {
        /// <summary>
        /// BITS calls your implementation of the JobTransferred method 
        /// when all of the files in the job have been successfully transferred. 
        /// For BG_JOB_TYPE_UPLOAD_REPLY jobs, BITS calls the JobTransferred method 
        /// after the upload file has been transferred to the server and the reply 
        /// has been transferred to the client. 
        /// </summary>
        /// <param name="pJob"></param>
        void JobTransferred(
            [MarshalAs(UnmanagedType.Interface)]    IBackgroundCopyJob pJob);


        /// <summary>
        /// BITS calls your implementation of the JobError method when the state of 
        /// the job changes to BG_JOB_STATE_ERROR. 
        /// </summary>
        /// <param name="pJob"></param>
        /// <param name="pError"></param>
        void JobError(
            [MarshalAs(UnmanagedType.Interface)]    IBackgroundCopyJob pJob,
            [MarshalAs(UnmanagedType.Interface)]    IBackgroundCopyError pError);

        /// <summary>
        /// BITS calls your implementation of the JobModification method when the job 
        /// has been modified. The service generates this event when bytes are transferred, 
        /// files have been added to the job, properties have been modified, or the state 
        /// of the job has changed.
        /// </summary>
        /// <param name="pJob"></param>
        /// <param name="dwReserved"></param>
        void JobModification(
            [MarshalAs(UnmanagedType.Interface)]    IBackgroundCopyJob pJob, 
            int dwReserved);



    }


	/// <summary>
	/// The BG_FILE_INFO structure provides the local and 
	/// remote names of the file to transfer
	/// </summary>
	[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0)]
	internal  struct _BG_FILE_INFO 
	{
		/// <summary>
		/// Remote Name for the File
		/// </summary>
		[MarshalAs(UnmanagedType.LPWStr)]
		public string RemoteName;

		/// <summary>
		/// Local Name for the file
		/// </summary>
		[MarshalAs(UnmanagedType.LPWStr)]
		public string LocalName;
	}

	/// <summary>
	/// The BG_JOB_PROGRESS structure provides job-related progress information, 
	/// such as the number of bytes and files transferred
	/// </summary>
	[StructLayoutAttribute(LayoutKind.Sequential, Pack=8, Size=0)]
	internal  struct _BG_JOB_PROGRESS 
	{
		/// <summary>
		/// Total number of bytes to transfer for the job.
		/// </summary>
		public ulong BytesTotal;

		/// <summary>
		/// Number of bytes transferred
		/// </summary>
		public ulong BytesTransferred;

		/// <summary>
		/// Total number of files to transfer for this job
		/// </summary>
		public uint FilesTotal;

		/// <summary>
		/// Number of files transferred. 
		/// </summary>
		public uint FilesTransferred;
	}


	/// <summary>
	/// The BG_JOB_TIMES structure provides job-related timestamps
	/// </summary>
	[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0)]
	internal  struct _BG_JOB_TIMES 
	{
		/// <summary>
		/// Time the job was created
		/// </summary>
		public long CreationTime;

		/// <summary>
		/// Time the job was last modified or bytes were transferred
		/// </summary>
		public long ModificationTime;

		/// <summary>
		/// Time the job entered the BG_JOB_STATE_TRANSFERRED state
		/// </summary>
		public long TransferCompletionTime;
	}

	
	///// <summary>
	///// FILETIME Structure
	///// </summary>
	//[StructLayoutAttribute(LayoutKind.Sequential, Pack=4, Size=0)]
	//internal  struct _FILETIME 
	//{
	//    /// <summary>
	//    /// Description
	//    /// </summary>
	//    public uint dwLowDateTime;

	//    /// <summary>
	//    /// Description
	//    /// </summary>
	//    public uint dwHighDateTime;
	//}

	/// <summary>
	/// The BG_FILE_PROGRESS structure provides file-related progress information, 
	/// such as the number of bytes transferred
	/// </summary>
	[StructLayoutAttribute(LayoutKind.Sequential, Pack=8, Size=0)]
	internal  struct _BG_FILE_PROGRESS 
	{
		/// <summary>
		/// Size of the file in bytes
		/// </summary>
		public ulong BytesTotal;

		/// <summary>
		/// Number of bytes transferred. 
		/// </summary>
		public ulong BytesTransferred;

		/// <summary>
		/// For downloads, the value is TRUE if the file is available to the user; 
		/// otherwise, the value is FALSE
		/// </summary>
		public int Completed;
	}

    [Flags()]
    internal enum BG_NOTIFY_FLAGS
    {
        BG_NOTIFY_JOB_TRANSFERRED = 0x0001,
        BG_NOTIFY_JOB_ERROR=0x0002,
        BG_NOTIFY_DISABLE=0x0004,
        BG_NOTIFY_JOB_MODIFICATION  =0x0008
    }

}

